Skip to content

adding function to print colored terminal output#554

Merged
imran-siddique merged 18 commits intomicrosoft:mainfrom
yacinemebarki:colored/terminal/output
Mar 30, 2026
Merged

adding function to print colored terminal output#554
imran-siddique merged 18 commits intomicrosoft:mainfrom
yacinemebarki:colored/terminal/output

Conversation

@yacinemebarki
Copy link
Copy Markdown
Contributor

@yacinemebarki yacinemebarki commented Mar 28, 2026

Description

Added colored output to the Python CLI for Agent-OS using rich. Created functions for each message type:

  • Added colored output to the Agent-OS Python CLI using rich:
    • error() – red text for errors (stderr)
    • success() – green text for success messages (stdout)
    • warn() – yellow text for warnings (stdout)
    • policy_violation() – bold red for policy violations (stderr)
    • passed_check() – green checkmark for passed checks (stdout)
  • Colored output is used in all CLI commands: validate, test, and diff
  • Normal output goes to stdout, errors go to stderr
  • Added test_cli_output.py in the tests folder to verify the functions
  • Removed obsolete YAML test files
  • Usage notes:
    • Output now has color codes to improve readability
    • If rich is not installed, CLI falls back to plain text
    • Optional flag --no-color can be added in future to disable colors

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Maintenance (dependency updates, CI/CD, refactoring)
  • Security fix

Package(s) Affected

  • agent-os-kernel
  • agent-mesh
  • agent-runtime
  • agent-sre
  • agent-governance
  • docs / root

Checklist

  • My code follows the project style guidelines (ruff check)
  • I have added tests that prove my fix/feature works
  • All new and existing tests pass (pytest)
  • I have updated documentation as needed
  • I have signed the Microsoft CLA

Related Issues

@github-actions
Copy link
Copy Markdown

Welcome to the Agent Governance Toolkit! Thanks for your first pull request.
Please ensure tests pass, code follows style (ruff check), and you have signed the CLA.
See our Contributing Guide.

@github-actions github-actions bot added the size/M Medium PR (< 200 lines) label Mar 28, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 28, 2026

🤖 AI Agent: test-generator — `packages/agent-os/src/agent_os/policies/cli.py`

🧪 Test Coverage Analysis

packages/agent-os/src/agent_os/policies/cli.py

  • Existing coverage:

    • The new colored output helper functions (error, success, warn, policy_violation, passed_check) are covered by the newly added test_cli_output.py.
    • CLI commands (validate, test, diff) are partially covered by test_policy_cli.py, which tests their functionality and error handling.
  • Missing coverage:

    • Edge cases for the colored output functions:
      • Behavior when rich is not installed (fallback to plain text).
      • Handling of the no_color flag (currently unused but mentioned in the code).
    • Comprehensive testing of CLI commands:
      • cmd_validate: Edge cases for invalid YAML/JSON files, malformed policies, and missing fields.
      • cmd_test: Scenarios with partial failures, cascading failures, and malformed inputs.
      • cmd_diff: Edge cases for conflicting policies, large policy files, and race conditions in file access.
  • 💡 Suggested test cases:

    1. test_error_fallback_plain_text — Verify that the error function correctly falls back to plain text output when rich is not installed.
    2. test_success_no_color — Test the success function with the no_color=True flag to ensure plain text output is used.
    3. test_cmd_validate_invalid_json — Validate behavior when an invalid JSON file is provided (e.g., syntax errors).
    4. test_cmd_validate_conflicting_policies — Test cmd_validate with policies that conflict with each other (e.g., overlapping conditions).
    5. test_cmd_test_partial_failures — Simulate scenarios where some tests pass and others fail, ensuring correct summary output.
    6. test_cmd_test_malformed_scenarios — Provide malformed scenario files to cmd_test and verify error handling.
    7. test_cmd_diff_large_files — Test cmd_diff with large policy files to ensure performance and correctness.
    8. test_cmd_diff_conflicting_policies — Verify behavior when comparing two policies with conflicting rules.
    9. test_cmd_diff_race_conditions — Simulate concurrent access to policy files during cmd_diff execution.

packages/agent-os/tests/test_cli_output.py

  • Existing coverage:

    • Covers basic functionality of the colored output helper functions (error, success, warn, policy_violation, passed_check).
  • Missing coverage:

    • Edge cases for fallback behavior when rich is not installed.
    • Handling of the no_color flag.
  • 💡 Suggested test cases:

    1. test_fallback_behavior_no_rich — Mock the absence of the rich library and verify that all helper functions fall back to plain text output.
    2. test_no_color_flag_behavior — Test all helper functions with the no_color=True flag to ensure plain text output is used.

packages/agent-os/tests/test_policy_cli.py

  • Existing coverage:

    • Covers basic functionality of CLI commands (validate, test, diff) and some error handling scenarios.
  • Missing coverage:

    • Edge cases for invalid inputs, conflicting policies, and large files.
    • Comprehensive testing of scenarios with partial failures, cascading failures, and race conditions.
  • 💡 Suggested test cases:

    1. test_cmd_validate_invalid_yaml — Validate behavior when an invalid YAML file is provided (e.g., syntax errors).
    2. test_cmd_validate_missing_fields — Test cmd_validate with policies missing required fields.
    3. test_cmd_test_cascading_failures — Simulate scenarios where failures cascade due to dependencies between tests.
    4. test_cmd_diff_large_files_performance — Measure performance and correctness when comparing large policy files.

By implementing these additional test cases, the repository can achieve better coverage for edge cases and ensure robustness in handling domain-specific scenarios.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 28, 2026

🤖 AI Agent: docs-sync-checker — Issues Found

📝 Documentation Sync Report

Issues Found

  • error(), success(), warn(), policy_violation(), passed_check() in packages/agent-os/src/agent_os/policies/cli.py — missing docstrings. These are public functions and should include docstrings explaining their purpose, parameters, return values, and exceptions.
  • ⚠️ packages/agent-os/README.md — no mention of the new colored output feature or the potential future --no-color flag.
  • ⚠️ CHANGELOG.md — no entry for the addition of the new colored output feature.
  • ⚠️ docs/ — no updates to project-level documentation to reflect the new colored output feature.
  • ⚠️ examples/ — no updates to example code to demonstrate the usage of the new colored output functions.

Suggestions

  • 💡 Add docstrings for the following functions in packages/agent-os/src/agent_os/policies/cli.py:
    • error(msg: str, no_color: bool = False) -> None
    • success(msg: str, no_color: bool = False) -> None
    • warn(msg: str, no_color: bool = False) -> None
    • policy_violation(msg: str, no_color: bool = False) -> None
    • passed_check(msg: str, no_color: bool = False) -> None
  • 💡 Update packages/agent-os/README.md to include a section on the new colored output feature, explaining the purpose of the new functions and the potential future --no-color flag.
  • 💡 Add an entry to CHANGELOG.md under a new version heading to document the addition of the colored output feature and the use of the rich library.
  • 💡 Update docs/ to include details about the new colored output feature and its usage in the CLI commands.
  • 💡 Add or update example code in examples/ to demonstrate the usage of the new colored output functions.

Additional Notes

  • The new functions are well-implemented and tested, but they lack proper documentation and type hints.
  • The addition of the rich library as a dependency should also be mentioned in the CHANGELOG.md and README.md.

Please address the above issues and suggestions to ensure the documentation and examples are in sync with the new functionality.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 28, 2026

🤖 AI Agent: breaking-change-detector — Summary

🔍 API Compatibility Report

Summary

This pull request introduces new functionality for colored terminal output in the Agent-OS CLI using the rich library. It adds several helper functions for formatted output and integrates them into existing CLI commands. No breaking changes were detected in the public API, and the changes are additive.

Findings

Severity Package Change Impact
🔵 agent-os Added error(), success(), warn(), policy_violation(), and passed_check() functions New public API for colored terminal output
🔵 agent-os Integrated rich library for enhanced CLI output Improves readability, no breaking changes

Migration Guide

No migration steps are necessary as no breaking changes were introduced. However, downstream users should be aware of the new colored output functionality and the optional dependency on the rich library.

Additional Notes

  • The new functions (error, success, warn, policy_violation, passed_check) are well-documented and tested.
  • If rich is not installed, the CLI gracefully falls back to plain text output.
  • The optional flag --no-color is mentioned as a potential future enhancement, which could provide additional flexibility for users.

No breaking changes detected.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 28, 2026

🤖 AI Agent: security-scanner — Security Review of PR: Adding Colored Terminal Output

Security Review of PR: Adding Colored Terminal Output

This PR introduces colored terminal output to the CLI using the rich library. While this change primarily enhances user experience, it touches critical parts of the CLI that interact with policy validation, error reporting, and test execution. Below is a security-focused review of the changes.


Findings

1. Prompt Injection Defense Bypass

Rating: 🔵 LOW
Details:
The rich library is used to format output, and user-provided strings (e.g., error messages, policy names) are passed directly to the Text object. While rich itself does not execute code from the strings, there is a potential risk if future changes introduce dynamic evaluation or if rich changes its behavior.
Fix:

  • Sanitize user-provided strings before passing them to rich.Text. For example, escape special characters or strip control sequences.
  • Add a test case to ensure no unexpected behavior occurs when malicious input (e.g., "\x1b[31mInjected\x1b[0m") is passed.

2. Policy Engine Circumvention

Rating: 🔵 LOW
Details:
The changes do not directly affect the policy engine logic. However, the use of colored output in error and success messages could obscure critical information if the output is misinterpreted or truncated in certain environments (e.g., CI logs).
Fix:

  • Provide a --no-color flag to disable colored output explicitly, ensuring compatibility with environments that do not support ANSI escape codes.
  • Add a warning in the documentation about potential issues with colored output in non-interactive environments.

3. Trust Chain Weaknesses

Rating: 🔵 LOW
Details:
This PR does not introduce or modify trust chain mechanisms (e.g., SPIFFE/SVID validation). No issues found.


4. Credential Exposure

Rating: 🔵 LOW
Details:
The changes do not log sensitive information. However, the use of rich for error messages could potentially expose sensitive data if exceptions or stack traces are printed without sanitization.
Fix:

  • Ensure that sensitive data (e.g., file paths, policy contents) is not included in error messages.
  • Add a test case to verify that sensitive data is not leaked in error output.

5. Sandbox Escape

Rating: 🔵 LOW
Details:
The changes do not introduce or modify sandboxing mechanisms. No issues found.


6. Deserialization Attacks

Rating: 🔵 LOW
Details:
This PR does not modify deserialization logic. However, the _load_file function (which loads YAML/JSON files) is used in CLI commands. If malicious files are loaded, they could exploit vulnerabilities in the YAML/JSON parser.
Fix:

  • Ensure that the YAML/JSON parser is configured to disable unsafe features (e.g., yaml.FullLoader instead of yaml.Loader).
  • Add a test case to verify that malicious YAML/JSON files do not cause unexpected behavior.

7. Race Conditions

Rating: 🔵 LOW
Details:
No race conditions were identified in the changes. The CLI commands are single-threaded and do not involve concurrent operations.


8. Supply Chain Risks

Rating: 🟠 HIGH
Details:
The rich library is added as a new dependency. While rich is a widely used and well-maintained library, introducing new dependencies always carries supply chain risks, such as dependency confusion or malicious updates.
Fix:

  • Pin the rich version in pyproject.toml to a specific version or range (e.g., rich>=13.0.0,<14.0.0).
  • Use a dependency scanner (e.g., pip-audit or safety) to monitor for vulnerabilities in rich.
  • Consider vendorizing the library if it becomes a critical dependency.

Additional Observations

  1. Error Handling in _import_console and _import_rich_text
    The _import_console and _import_rich_text functions print warnings to stderr if the rich library is not installed. This behavior is acceptable but could be improved by raising a custom exception or falling back to plain text output without warnings.

  2. Test Coverage
    The new test file (test_cli_output.py) provides good coverage for the colored output functions. However, additional tests should be added to verify behavior with malicious input (e.g., strings containing ANSI escape codes).

  3. Backward Compatibility
    The changes maintain backward compatibility by falling back to plain text output if rich is not installed. This is a good practice.


Summary of Recommendations

  • 🔵 Sanitize user-provided strings before passing them to rich.Text.
  • 🔵 Add a --no-color flag to disable colored output explicitly.
  • 🔵 Ensure sensitive data is not leaked in error messages.
  • 🔵 Configure YAML/JSON parsers to disable unsafe features.
  • 🟠 Pin the rich version to mitigate supply chain risks.
  • 🟠 Use a dependency scanner to monitor for vulnerabilities in rich.

Final Rating: 🟡 MEDIUM

While the changes themselves are low-risk, the introduction of a new dependency (rich) increases the overall attack surface. Addressing the supply chain risks and ensuring proper sanitization will mitigate potential vulnerabilities.

@github-actions
Copy link
Copy Markdown

🤖 AI Agent: contributor-guide — Welcome! 🎉

Welcome! 🎉

Hi there, and welcome to the microsoft/agent-governance-toolkit project! Thank you so much for taking the time to contribute to this repository. We’re thrilled to have you here, and we appreciate your effort in improving the project. 😊


PR Review 🧐

First off, great job on this pull request! Here’s what I really liked about your contribution:

  1. Clear Description: Your PR description is detailed and well-structured. It’s clear what you’re trying to achieve, and the breakdown of the functions is super helpful.
  2. Thoughtful Design: The use of the rich library for colored terminal output is a fantastic choice. It’s a well-maintained library that aligns with modern Python practices.
  3. Test Coverage: You’ve included test scenarios and policies to validate the new functionality, which is excellent. This shows you’re thinking about how others will use and verify your code.
  4. Code Quality: The code is clean and easy to read, and I appreciate how you’ve replaced repetitive print statements with reusable functions like error() and success().

Suggestions for Improvement ✨

Here are a few suggestions to align your contribution with our project conventions and best practices:

  1. Linting:

    • We use ruff for linting with the E, F, and W error codes enabled. While your code looks clean, please run ruff check to ensure it adheres to our linting rules. You can install ruff via pip if you haven’t already:
      pip install ruff
      ruff check .
  2. Test Placement:

    • While I see you’ve added test scenarios in test_policies, our convention is to place tests in the tests/ folder within the relevant package. For this PR, the test files should be moved to packages/agent-os/tests/. This helps keep tests organized and consistent across the project.
  3. Conventional Commits:

    • We follow the Conventional Commits specification for commit messages. For example, your commit message could be updated to something like:
      feat(cli): add colored terminal output using rich library
      
      This makes it easier to understand the purpose of changes at a glance.
  4. Documentation:

    • While your code is self-explanatory, it would be great to update the relevant documentation to mention the new colored output feature. You can add this to the CLI section in the QUICKSTART.md file.
  5. Security Considerations:

    • Since this is a CLI enhancement and doesn’t directly handle sensitive data, it seems low-risk from a security perspective. However, if there’s any user input involved in the messages, ensure it’s sanitized to avoid potential injection vulnerabilities.

Resources 📚

Here are some helpful links to get you up to speed with our project conventions:


Next Steps 🚀

  1. Run ruff check and address any linting issues.
  2. Move your test files to packages/agent-os/tests/.
  3. Update your commit message to follow the Conventional Commits format.
  4. Update the documentation in QUICKSTART.md to reflect the new feature.
  5. Push your changes to this branch, and they’ll automatically update this PR.

Once you’ve made these updates, I’ll take another look and help you get this merged! Let me know if you have any questions or need assistance with anything. 😊

Thank you again for your contribution — we’re excited to have you on board! 🚀

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review Summary

This pull request introduces a new feature to enhance the CLI output of the agent-governance package by adding color-coded messages using the rich library. The changes improve the user experience by making CLI feedback more visually distinct and easier to interpret. The PR also includes test policies and scenarios to validate the new functionality.

While the changes are generally well-implemented, there are a few areas that need attention to ensure robustness, security, and maintainability.


🔴 CRITICAL

  1. Unvalidated User Input in CLI Commands:

    • The CLI commands (cmd_validate, cmd_test, cmd_diff) directly use user-supplied file paths without sufficient validation or sanitization. This could lead to potential path traversal vulnerabilities or arbitrary file access.
    • Recommendation: Use os.path.abspath to normalize paths and ensure they are within an expected directory. Additionally, validate the file extensions and ensure that only .yaml or .json files are processed.
  2. Error Messages May Leak Sensitive Information:

    • The error messages in the cmd_validate, cmd_test, and cmd_diff functions include the exception message (exc) directly in the output. This could expose sensitive information about the system or stack traces in production environments.
    • Recommendation: Log detailed exception messages to a secure log file and provide generic error messages to the user.

🟡 WARNING

  1. Backward Compatibility:
    • The new rich-based output changes the format of CLI messages, which could break existing scripts or tools that parse the CLI output.
    • Recommendation: Add a --plain or --no-color flag to allow users to disable colored output and revert to plain text. This ensures backward compatibility for users relying on the previous output format.

💡 SUGGESTIONS

  1. Error Handling Consistency:

    • The cmd_validate, cmd_test, and cmd_diff functions use inconsistent return codes for errors. For example, cmd_validate returns 2 for file-not-found errors, while cmd_test also uses 2 for parsing errors.
    • Recommendation: Define a consistent set of exit codes for different error types (e.g., 1 for validation errors, 2 for file-not-found errors, etc.) and document them.
  2. Unit Tests for Colored Output:

    • While the PR includes test policies and scenarios, there are no explicit unit tests for the new colored output functions (error, success, warn, etc.).
    • Recommendation: Add unit tests to verify that the rich-based functions produce the expected output. You can use the pytest library's capsys fixture to capture and assert the printed output.
  3. Optional Dependency Management:

    • The rich library is now a required dependency, but it may not be necessary for all users or environments.
    • Recommendation: Consider making rich an optional dependency and provide a fallback to plain text output if it is not installed. Alternatively, document the new dependency clearly in the README and installation instructions.
  4. Code Duplication in Error Messages:

    • The error-handling code in cmd_validate, cmd_test, and cmd_diff is repetitive.
    • Recommendation: Refactor the error-handling logic into a helper function (e.g., handle_error) to reduce duplication and improve maintainability.
  5. Default File Encoding:

    • The _load_file function does not specify an encoding when reading files. This could lead to issues on systems with non-UTF-8 default encodings.
    • Recommendation: Explicitly specify encoding="utf-8" when reading files to ensure consistent behavior across platforms.
  6. Type Annotations for New Functions:

    • The new functions (error, success, warn, etc.) lack type annotations.
    • Recommendation: Add type annotations to improve code readability and maintainability. For example:
      def error(msg: str) -> None:
          ...
  7. Documentation Update:

    • The PR does not include updates to the documentation to reflect the new CLI output format or the addition of the rich dependency.
    • Recommendation: Update the CLI documentation to describe the new color-coded output and any new flags (e.g., --plain).

Additional Observations

  1. Use of sys.stderr:

    • The new output functions (error, success, etc.) write to sys.stderr for all message types, including success messages. While this is acceptable for error messages, success messages are typically written to sys.stdout.
    • Recommendation: Use sys.stdout for non-error messages like success and passed_check.
  2. Unused Test Files:

    • The new test files (test_policy_messages.yaml, test_scenarios_messages.yaml, test_success.yaml) are added but not integrated into the test suite.
    • Recommendation: Ensure these files are used in automated tests to validate the new functionality.

Summary of Changes Required

🔴 CRITICAL

  • Validate and sanitize user-supplied file paths to prevent path traversal and arbitrary file access.
  • Avoid exposing sensitive information in error messages.

🟡 WARNING

  • Add a --plain or --no-color flag to maintain backward compatibility with plain text output.

💡 SUGGESTIONS

  • Define consistent exit codes for CLI commands.
  • Add unit tests for the new colored output functions.
  • Consider making rich an optional dependency or document it clearly.
  • Refactor repetitive error-handling code into a helper function.
  • Specify encoding="utf-8" when reading files.
  • Add type annotations to the new functions.
  • Update CLI documentation to reflect the new output format and dependency.
  • Use sys.stdout for non-error messages.
  • Integrate the new test files into the test suite.

Final Assessment

The PR introduces a useful feature that improves the user experience of the CLI. However, it introduces potential security risks and backward compatibility concerns that must be addressed before merging.

Copy link
Copy Markdown
Member

@imran-siddique imran-siddique left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution @yacinemebarki! The colored output is a nice UX improvement, but a few issues:

  1. New dependency not declared — \ rom rich import print\ adds a runtime dependency on
    ich, but agent-os-kernel's pyproject.toml only requires \pydantic. Either add
    ich\ to dependencies or make it a lazy/optional import with fallback.

  2. Shadows built-in — \ rom rich import print\ shadows Python's built-in \print. Use \ rom rich import print as rprint\ or \ rom rich.console import Console.

  3. Output to stderr — All the color functions print to \sys.stderr. The validate command's normal output should go to stdout; only errors to stderr.

  4. Removed blank lines — Several blank line removals change the code style without adding value. Please keep formatting changes minimal.

Please fix these and I'll re-review.

@github-actions github-actions bot added the tests label Mar 28, 2026
Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review of Pull Request: Adding Function to Print Colored Terminal Output


Summary

This PR introduces a new feature to enhance the CLI output of the agent-governance package by adding colored terminal output using the rich library. It includes new functions for different message types (error, success, warn, policy_violation, passed_check) and updates the CLI commands (validate, test, diff) to use these functions. A new test script (test_cli_output.py) is also added to demonstrate the functionality.


Review

1. Policy Engine Correctness

  • The changes in this PR do not directly affect the policy engine's logic or decision-making. The modifications are limited to improving the CLI output for better user experience. No issues identified in this area.

2. Trust/Identity: Cryptographic Operations, Credential Handling, SPIFFE/SVID

  • This PR does not introduce or modify any cryptographic operations, credential handling, or SPIFFE/SVID-related functionality. No issues identified in this area.

3. Sandbox Escape Vectors

  • The changes do not introduce any new sandbox escape vectors. The rich library is a well-known and widely used library for terminal output formatting. However, it is important to ensure that user-controlled input is sanitized before being passed to the rich.print function to avoid potential injection attacks.
  • 🔴 CRITICAL: The error, warn, policy_violation, and other functions directly pass user-controlled input (msg) to the rich.print function without sanitization. This could lead to potential injection attacks if the input contains malicious ANSI escape sequences. Consider sanitizing the input to prevent abuse.

4. Thread Safety in Concurrent Agent Execution

  • The functions introduced in this PR (error, success, etc.) are not thread-safe. If multiple threads call these functions simultaneously, the output may become interleaved, leading to garbled or unreadable terminal output.
  • 💡 SUGGESTION: Use a thread-safe mechanism (e.g., a threading.Lock) to ensure that only one thread writes to the terminal at a time.

5. OWASP Agentic Top 10 Compliance

  • The changes do not introduce any direct violations of OWASP Agentic Top 10 principles. However, as mentioned earlier, the lack of input sanitization for terminal output could potentially lead to security issues.

6. Type Safety and Pydantic Model Validation

  • The new functions (error, success, etc.) do not use type hints for their parameters. While this is not a critical issue, adding type hints would improve code readability and maintainability.
  • 💡 SUGGESTION: Add type hints to the new functions. For example:
    def error(msg: str) -> None:
        ...

7. Backward Compatibility

  • The changes in this PR are non-breaking, as they only modify the CLI output and do not affect the existing API or functionality. No issues identified in this area.

8. Testing

  • A new test script (test_cli_output.py) is included to demonstrate the functionality of the new CLI output functions. However, this script is not integrated into the automated test suite and does not use the pytest framework.
  • 💡 SUGGESTION: Convert the test script into proper unit tests using pytest. For example:
    import pytest
    from rich.console import Console
    from agent_os.policies.cli import success, error, warn, policy_violation, passed_check
    
    @pytest.fixture
    def console():
        return Console()
    
    def test_success(console, capsys):
        success("Test success message")
        captured = capsys.readouterr()
        assert "[green]Test success message[/green]" in captured.err
    
    def test_error(console, capsys):
        error("Test error message")
        captured = capsys.readouterr()
        assert "[red]Test error message[/red]" in captured.err
    
    # Add similar tests for warn, policy_violation, and passed_check

Recommendations

  1. 🔴 CRITICAL: Sanitize user-controlled input (msg) before passing it to the rich.print function to prevent potential injection attacks via ANSI escape sequences.

    • Consider using a library like html or re to escape or sanitize input strings.
  2. 💡 SUGGESTION: Add type hints to the new functions for better code readability and maintainability.

  3. 💡 SUGGESTION: Ensure thread safety for the new functions by using a threading.Lock or similar mechanism to prevent interleaved output in multi-threaded scenarios.

  4. 💡 SUGGESTION: Integrate the new test script into the automated test suite using the pytest framework. This will ensure that the new functionality is tested consistently during CI/CD runs.

  5. 💡 SUGGESTION: Update the documentation to include details about the new CLI output functions and their usage.


Final Assessment

  • The PR introduces a useful feature for improving the user experience of the CLI.
  • However, the lack of input sanitization for terminal output is a critical security issue that must be addressed before merging.
  • Once the critical issue is resolved and the suggested improvements are implemented, the PR will be ready for approval.

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review Summary

This pull request introduces a new feature to enhance the CLI output of the agent-governance package by adding colored terminal output using the rich library. It also includes a new test script to verify the functionality of the colored output functions. While the feature improves the user experience, there are several areas that require attention to ensure robustness, maintainability, and security.


🔴 CRITICAL

  1. Unvalidated User Input in CLI Functions:

    • The error, success, warn, policy_violation, and passed_check functions directly pass user-provided messages to the print function without sanitization or validation. This could lead to unintended behavior, such as terminal escape sequence injection.
    • Recommendation: Sanitize or validate the input to ensure no malicious escape sequences are passed. For example:
      from rich.text import Text
      def error(msg):
          sanitized_msg = Text.from_markup(msg, style="red")
          print(sanitized_msg, file=sys.stderr)
  2. Test Coverage for CLI Functions:

    • The test_cli_output.py script does not include automated tests. Instead, it relies on manual inspection of the terminal output.
    • Recommendation: Replace the manual test script with automated tests using a library like pytest and pytest-console-scripts or pytest-capturelog. This will ensure that the output is consistently validated in CI/CD pipelines.

🟡 WARNING

  1. Backward Compatibility:
    • The PR replaces all existing print statements with calls to the new functions. While this is a non-breaking change in terms of functionality, it alters the appearance of the CLI output, which may impact users relying on the previous format (e.g., for parsing logs).
    • Recommendation: Add a configuration flag (e.g., --no-color) to allow users to disable colored output and revert to plain text if needed. This ensures backward compatibility.

💡 SUGGESTIONS

  1. Use a Logging Library:

    • Instead of using print statements, consider using Python's built-in logging module with a custom handler for rich-formatted output. This approach provides better flexibility, configurability, and integration with existing logging systems.
    • Example:
      from rich.logging import RichHandler
      import logging
      
      logging.basicConfig(level="INFO", handlers=[RichHandler()])
      logger = logging.getLogger("agent-governance")
      
      def error(msg):
          logger.error(msg)
  2. Thread Safety:

    • The print function is not thread-safe. If the CLI is used in a multithreaded context, concurrent calls to these functions could result in interleaved or corrupted output.
    • Recommendation: Use a thread-safe logging mechanism or a thread-safe wrapper around print.
  3. Dependency Management:

    • The rich library is introduced as a new dependency but is not added to the requirements.txt or pyproject.toml file.
    • Recommendation: Add rich to the appropriate dependency file to ensure it is installed during deployment.
  4. Function Naming:

    • The function names (error, success, etc.) are generic and could potentially conflict with other parts of the codebase or third-party libraries.
    • Recommendation: Use more descriptive names, such as print_error, print_success, etc., to avoid potential naming conflicts.
  5. Documentation:

    • The PR does not include updates to the documentation to reflect the new CLI behavior.
    • Recommendation: Update the CLI documentation to describe the new colored output and any new configuration options (e.g., --no-color).
  6. Unit Test Assertions:

    • The test script does not include assertions to verify the correctness of the output.
    • Recommendation: Use pytest and capture the output of the CLI functions to assert that the correct colors and formats are applied. For example:
      from rich.console import Console
      from io import StringIO
      
      def test_error_output():
          console = Console(file=StringIO())
          error("Test error message", console=console)
          output = console.file.getvalue()
          assert "[red]Test error message[/red]" in output
  7. File Naming for Tests:

    • The test file is named test_cli_output.py, but it does not follow the naming conventions of the existing test suite.
    • Recommendation: Rename the file to match the project's test naming conventions (e.g., test_policies_cli.py).

Final Assessment

  • Security: 🔴 CRITICAL issues related to unvalidated user input in CLI functions.
  • Backward Compatibility: 🟡 WARNING due to changes in CLI output format.
  • Code Quality: 💡 Several suggestions for improvement, including better test coverage, thread safety, and dependency management.

Action Items

  1. Address the critical security issue by sanitizing user input in CLI functions.
  2. Add automated tests for the new functions to ensure consistent behavior.
  3. Introduce a --no-color flag to maintain backward compatibility.
  4. Consider using a logging library for better flexibility and thread safety.
  5. Update the documentation to reflect the new CLI behavior.
  6. Add rich to the dependency management files.
  7. Rename the test file to align with the project's conventions.

Let me know if you need further clarification or assistance!

@github-actions github-actions bot added the size/L Large PR (< 500 lines) label Mar 28, 2026
Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review of Pull Request: Adding Function to Print Colored Terminal Output


Summary:

This PR introduces a new feature to the agent-governance package by adding colored terminal output to the CLI using the rich library. It includes helper functions for different message types (error, success, warn, policy_violation, passed_check) and updates the CLI commands (validate, test, diff) to use these functions. A new test script (test_cli_output.py) is also added to verify the functionality.


Feedback:

🔴 CRITICAL

  1. Error Handling for Missing rich Library:

    • The fallback mechanism for when rich is not installed (rprint defaults to print) is insufficient for a security-focused library. If rich is not installed, the CLI will silently degrade to unformatted output, which could lead to confusion or missed critical messages.

    • Recommendation: Explicitly check for the presence of rich during initialization and fail with a clear error message if it is not installed. This ensures that the library's behavior is consistent and predictable.

      try:
          from rich import print as rprint
      except ImportError:
          sys.stderr.write("ERROR: The 'rich' library is required for this CLI. Please install it using 'pip install rich'.\n")
          sys.exit(2)
  2. Potential Information Disclosure in Error Messages:

    • The error and policy_violation functions directly output exception messages (e.g., f"ERROR: failed to parse {path}: {exc}"). This could expose sensitive information (e.g., file paths, stack traces) to unauthorized users.
    • Recommendation: Sanitize error messages to avoid leaking sensitive information. For example:
      error(f"ERROR: failed to parse {path}. Please check the file format.")
  3. Testing Script (test_cli_output.py):

    • The test script is not a proper unit test. It is a standalone script that requires manual execution and observation of output, which is not suitable for automated CI/CD pipelines.
    • Recommendation: Replace the script with proper unit tests using pytest and mock the rprint function to verify the output. For example:
      from unittest.mock import patch
      from agent_os.policies.cli import success, error
      
      def test_success_output():
          with patch("rich.print") as mock_rprint:
              success("Test passed")
              mock_rprint.assert_called_once_with("[green]Test passed[/green]")
      
      def test_error_output():
          with patch("rich.print") as mock_rprint:
              error("Test failed")
              mock_rprint.assert_called_once_with("[red]Test failed[/red]", file=sys.stderr)

🟡 WARNING

  1. Backward Compatibility:

    • The changes replace all instances of print with rprint or the new helper functions. While this improves readability and user experience, it may break existing scripts or integrations that rely on the previous plain-text output.
    • Recommendation: Add a CLI flag (e.g., --no-color) to allow users to disable colored output and revert to plain-text messages. This ensures backward compatibility for users who rely on parsing the CLI output.
  2. Removed YAML Test Files:

    • The PR mentions the removal of "obsolete YAML test files" but does not provide details. If these files were used in existing tests, their removal could break the test suite or reduce coverage.
    • Recommendation: Ensure that the removal of these files does not impact test coverage. If they are no longer needed, provide a clear explanation in the PR description.

💡 SUGGESTIONS

  1. Improved Logging:

    • Consider integrating a logging library (e.g., Python's logging module) for better control over message formatting and levels. This would allow for more granular control over output (e.g., debug, info, warning, error) and make it easier to redirect logs to files or other outputs.
  2. Thread Safety:

    • While the changes in this PR do not introduce threading, the use of global functions like rprint could lead to issues in a multithreaded environment if future changes introduce concurrency.
    • Recommendation: Ensure that the CLI functions are thread-safe by avoiding shared mutable state or using thread-local storage if necessary.
  3. Documentation:

    • Update the CLI documentation to reflect the new colored output and the meaning of each color/style. If a --no-color flag is added, document its usage as well.
  4. Code Style:

    • Some comments and docstrings have been removed or simplified (e.g., in cmd_validate, cmd_test, and cmd_diff). While this reduces verbosity, it also makes the code less self-explanatory.
    • Recommendation: Retain or enhance comments and docstrings to ensure clarity, especially for critical functions.
  5. Testing Coverage:

    • Extend test coverage to include edge cases, such as:
      • Missing or malformed policy files.
      • Scenarios with unexpected data types or missing keys.
      • CLI commands with invalid arguments.

Actionable Summary:

  1. 🔴 Critical: Improve error handling for missing rich library and sanitize error messages to avoid information disclosure.
  2. 🟡 Warning: Add a --no-color flag for backward compatibility and verify the impact of removed YAML test files.
  3. 💡 Suggestions: Replace the standalone test script with proper unit tests, enhance documentation, and ensure thread safety.

Once these issues are addressed, the PR will be in a much stronger position for merging.

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review of Pull Request: Adding Function to Print Colored Terminal Output


General Feedback

This PR introduces a new feature to enhance the CLI output by adding color-coded messages using the rich library. The feature is well-scoped and improves the user experience by making the CLI output more readable and visually distinct. The implementation is clean and follows the project's coding style. However, there are a few areas that need attention to ensure robustness, maintainability, and security.


🔴 CRITICAL

  1. Dynamic Import of rich Library:

    • The _import_rprint function dynamically imports the rich library at runtime. While this is a fallback mechanism for environments where rich might not be installed, it introduces potential security risks, as dynamic imports can be exploited if the environment is compromised.
    • Recommendation: Instead of dynamically importing rich, add it as a required dependency in the requirements.txt or pyproject.toml file. This ensures that the library is always available and avoids runtime surprises.
  2. Error Handling in _import_rprint:

    • If rich is not installed, _import_rprint silently falls back to print. This could lead to inconsistent behavior across environments.
    • Recommendation: If rich is a required dependency, raise an exception if it is not installed. If it is optional, log a warning to inform the user that colored output is disabled due to the missing dependency.

🟡 WARNING

  1. Potential Breaking Change in CLI Output:
    • The PR replaces plain text output with color-coded output. While this is a non-breaking change in terms of functionality, it could affect users or systems that parse the CLI output programmatically.
    • Recommendation: Add a CLI flag (e.g., --no-color) to disable colored output and revert to plain text. This ensures backward compatibility for users who rely on the plain text format.

💡 SUGGESTIONS

  1. Test Coverage:

    • The test_cli_output.py file is more of a manual testing script than an automated test. It does not verify the correctness of the output programmatically.
    • Recommendation: Use a testing framework like pytest to capture and assert the output of the colored functions. For example, use capsys (a pytest fixture) to capture printed output and compare it against expected values.

    Example:

    def test_success_output(capsys):
        success("Test passed")
        captured = capsys.readouterr()
        assert "[green]Test passed[/green]" in captured.out
  2. Centralized Import of rich:

    • The _import_rprint function is called repeatedly in each helper function, which is inefficient and could lead to inconsistent behavior.
    • Recommendation: Perform the rich import once at the module level and handle the fallback to print there. For example:
      try:
          from rich import print as rprint
      except ImportError:
          rprint = print
  3. Documentation:

    • The PR does not include updates to the documentation. Users need to know about the new colored output feature and how to use it.
    • Recommendation: Update the CLI documentation to mention the new color-coded output and any new flags (e.g., --no-color if implemented).
  4. Code Duplication:

    • The color-coded output functions (error, success, warn, etc.) have repetitive code for importing rprint and checking if it is None.
    • Recommendation: Refactor the functions to reduce duplication. For example:
      def print_colored(msg: str, color: str, is_bold: bool = False, is_error: bool = False) -> None:
          style = f"[{color}]{msg}[/{color}]"
          if is_bold:
              style = f"[bold]{style}[/bold]"
          rprint = _import_rprint()
          if rprint is not None:
              rprint(style, file=sys.stderr if is_error else sys.stdout)
          else:
              print(msg, file=sys.stderr if is_error else sys.stdout)
  5. Unicode Compatibility:

    • The passed_check function uses a Unicode checkmark (\u2714). While this enhances readability, it may not render correctly in all terminal environments.
    • Recommendation: Provide a fallback for environments that do not support Unicode, or allow users to disable Unicode characters via a CLI flag.
  6. Testing Edge Cases:

    • The current implementation does not test edge cases, such as very long messages, multiline messages, or messages containing special characters.
    • Recommendation: Add tests to cover these scenarios to ensure the functions handle them gracefully.
  7. Performance Considerations:

    • The repeated calls to _import_rprint could have a minor performance impact, especially in scenarios where the CLI is invoked frequently.
    • Recommendation: Cache the result of _import_rprint to avoid redundant imports.

Summary of Actionable Feedback

🔴 CRITICAL

  • Replace dynamic import of rich with a static import and add it as a required dependency.
  • Improve error handling in _import_rprint to avoid silent failures.

🟡 WARNING

  • Add a --no-color flag to ensure backward compatibility for users relying on plain text output.

💡 SUGGESTIONS

  • Replace manual testing script with automated tests using pytest.
  • Refactor color-coded output functions to reduce code duplication.
  • Update documentation to reflect the new feature.
  • Add fallback for Unicode characters in passed_check.
  • Test edge cases for message formatting.
  • Cache the result of _import_rprint to improve performance.

Final Notes

The feature is a valuable addition to the project, enhancing the user experience for the CLI. Addressing the above feedback will ensure the implementation is robust, secure, and backward-compatible. Let me know if you need further clarification or assistance!

@yacinemebarki
Copy link
Copy Markdown
Contributor Author

yacinemebarki commented Mar 28, 2026

Thanks for the thorough review! @imran-siddique I've addressed all four points and tried to implimented:

  1. Lazy optional importrich is now imported inside a _import_rprint() helper that falls back to plain print if rich isn't installed, so no new hard dependency is introduced.
  2. No more shadowing — using from rich import print as rprint scoped locally inside each helper, so the built-in print is never touched at module level.
  3. Correct stderr/stdout routingerror() is the only function that writes to sys.stderr; success(), warn(), policy_violation(), and passed_check() all write to stdout.
  4. Blank lines restored — all original blank lines and code structure are preserved; only the print(...) call-sites were replaced with the new helpers.

Let me know if anything else needs adjusting!

@yacinemebarki
Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree

@github-actions github-actions bot added the dependencies Pull requests that update a dependency file label Mar 29, 2026
Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review Summary

This pull request introduces a new feature to enhance the CLI output of the agent-os package by adding support for colored terminal output using the rich library. It also includes new utility functions for different message types (error, success, warn, policy_violation, passed_check) and updates the CLI commands (validate, test, diff) to use these functions. Additionally, tests for the new functionality have been added.

The changes are well-structured and improve the user experience by making the CLI output more readable. However, there are a few areas that need attention to ensure the robustness, security, and maintainability of the code.


🔴 CRITICAL

  1. Dynamic Import of rich Library

    • The _import_rprint function dynamically imports the rich library at runtime. This approach could lead to potential security vulnerabilities if the rich module is replaced or tampered with in the Python environment.
    • Recommendation: Instead of dynamically importing rich, add it as a required dependency in pyproject.toml and import it statically at the top of the file. If you want to support environments without rich, consider using a feature flag or environment variable to conditionally enable/disable colored output.
  2. Policy Violation Output to stderr

    • The policy_violation function outputs to stdout instead of stderr. Policy violations are critical errors and should be directed to stderr for proper logging and error handling.
    • Recommendation: Update the policy_violation function to use file=sys.stderr when calling rprint or print.

🟡 WARNING

  1. Backward Compatibility
    • The introduction of colored output changes the format of the CLI output, which could potentially break scripts or tools that parse the output of the CLI commands.
    • Recommendation: Add a --no-color flag to allow users to disable colored output and maintain compatibility with existing workflows. This flag should default to False to preserve the current behavior.

💡 SUGGESTIONS

  1. Test Coverage

    • While the new utility functions are tested, the tests only check for the presence of specific substrings in the output. This approach does not verify the presence of color codes or formatting.
    • Recommendation: Use the rich library's Console object with a custom io.StringIO file to capture and verify the actual formatted output. This will ensure that the color codes and formatting are applied correctly.
  2. Error Handling for Missing rich

    • The fallback to plain text when rich is not installed is a good approach. However, it might be helpful to log a warning message (e.g., "Rich library not found, falling back to plain text output.") to inform users about the fallback.
    • Recommendation: Add a one-time warning message when the rich library is not found.
  3. Function Naming

    • The function names (error, success, warn, etc.) are clear, but they could be more descriptive to avoid potential conflicts with other modules or libraries.
    • Recommendation: Consider prefixing the function names with cli_ or output_ (e.g., cli_error, cli_success) to make them more specific to the CLI context.
  4. Code Duplication in _import_rprint Usage

    • The repeated calls to _import_rprint in each utility function introduce unnecessary duplication.
    • Recommendation: Refactor _import_rprint to a module-level variable (e.g., RPRINT) that is initialized once and reused across all functions.
  5. Documentation

    • The PR mentions that documentation updates are not included. However, the new functionality should be documented, especially for users who might want to disable colored output in the future.
    • Recommendation: Update the CLI documentation to describe the new colored output feature and the potential addition of a --no-color flag.
  6. Test Cases for CLI Commands

    • The current tests only cover the utility functions but do not test the integration of these functions into the validate, test, and diff commands.
    • Recommendation: Add integration tests for the CLI commands to ensure that the colored output works as expected in different scenarios.
  7. Unicode Handling

    • The passed_check function uses the Unicode checkmark character (\u2714). While this improves readability, it may not render correctly in all terminal environments.
    • Recommendation: Provide a fallback option for environments that do not support Unicode characters.

Summary of Changes Needed

Critical

  1. Replace dynamic import of rich with a static import or feature flag.
  2. Update policy_violation to output to stderr.

Warning

  1. Add a --no-color flag to maintain backward compatibility.

Suggestions

  1. Improve test coverage to verify color codes and formatting.
  2. Log a warning when rich is not installed and falling back to plain text.
  3. Refactor function names to avoid potential conflicts.
  4. Refactor _import_rprint to a module-level variable to reduce duplication.
  5. Update documentation to include details about the new feature.
  6. Add integration tests for CLI commands.
  7. Provide a fallback for Unicode characters in passed_check.

These changes will improve the security, maintainability, and usability of the new feature while minimizing the risk of breaking existing workflows.

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review Summary

This PR introduces a new feature to enhance the CLI output of the agent-os package by adding colored text using the rich library. It also includes fallback behavior for environments where rich is not installed. The changes are well-structured and include tests to verify the functionality of the new output methods. However, there are some areas that require attention to ensure robustness, security, and maintainability.


🔴 CRITICAL

  1. Dynamic Import of rich Library:

    • The _import_rprint function dynamically imports the rich library. While this is done to provide a fallback mechanism, it introduces a potential security risk if the rich module is replaced or tampered with in the environment.
    • Recommendation: Instead of dynamically importing rich, make it a required dependency in pyproject.toml and handle the --no-color flag explicitly to disable colored output. This ensures the library is always available and avoids runtime import risks.
  2. Policy Violation Output to stdout:

    • The policy_violation function outputs to stdout instead of stderr. Policy violations are critical errors and should be directed to stderr to ensure proper logging and error handling.
    • Recommendation: Update the policy_violation function to use sys.stderr for output.

🟡 WARNING

  1. Backward Compatibility:
    • The PR introduces colored output to the CLI, which may break existing scripts or tools that parse the CLI output (e.g., CI pipelines or log parsers). Even though the fallback to plain text is implemented, the default behavior is now colored output.
    • Recommendation: Add a --no-color flag to explicitly disable colored output, as mentioned in the PR description. This ensures backward compatibility for users who rely on plain text output.

💡 SUGGESTIONS

  1. Test Coverage:

    • The new tests in test_cli_output.py verify the presence of specific strings in the output but do not test the actual color codes when rich is installed.
    • Recommendation: Use pytest-mock or a similar library to mock the rich.print function and verify that the correct color codes are being passed to it.
  2. Error Handling for rich Import:

    • The _import_rprint function silently falls back to print if rich is not installed. While this is acceptable, it might be helpful to log a warning message to inform users that colored output is disabled due to the missing dependency.
    • Recommendation: Add a warning log when rich is not installed, so users are aware of the fallback.
  3. Code Duplication:

    • The _import_rprint function is called repeatedly in each helper function, leading to redundant imports.
    • Recommendation: Import rich once at the module level and use a global flag to determine whether to use colored output or plain text. This will improve performance and reduce code duplication.
  4. Documentation:

    • The PR does not include updates to the documentation, which is marked as incomplete in the checklist.
    • Recommendation: Update the CLI documentation to include details about the new colored output and the potential addition of the --no-color flag.
  5. Error Message Consistency:

    • Some error messages use "ERROR:" while others do not. Consistency in error message formatting improves readability and debugging.
    • Recommendation: Standardize error message prefixes across all functions.
  6. Unicode Handling:

    • The passed_check function uses a Unicode checkmark (\u2714). While this is visually appealing, it may not render correctly in all terminal environments.
    • Recommendation: Provide a fallback for environments that do not support Unicode, or allow users to disable Unicode symbols via a CLI flag.

Additional Notes

  • The use of rich is a good choice for enhancing CLI output, as it is a well-maintained and widely used library.
  • The fallback mechanism for environments without rich is a thoughtful addition, but it could be improved as suggested above.
  • The removal of obsolete YAML test files is a good cleanup step, but it should be mentioned explicitly in the PR description as part of the "Maintenance" category.

Suggested Actions

  1. Address the CRITICAL issues:

    • Make rich a required dependency.
    • Update policy_violation to output to stderr.
  2. Address the WARNING issue:

    • Add a --no-color flag to disable colored output.
  3. Consider implementing the SUGGESTIONS:

    • Improve test coverage for color codes.
    • Add a warning log for missing rich.
    • Refactor _import_rprint to avoid redundant imports.
    • Update documentation for the new feature.
    • Standardize error message formatting.
    • Add a fallback for Unicode symbols.

Final Assessment

The PR introduces a useful feature that improves the readability of CLI output. However, the dynamic import of rich and the use of stdout for critical policy violation messages are significant issues that need to be addressed before merging. Additionally, the potential for breaking changes due to the introduction of colored output should be mitigated by adding a --no-color flag. Once these issues are resolved, the PR will be ready for approval.

@imran-siddique imran-siddique enabled auto-merge (squash) March 29, 2026 20:34
auto-merge was automatically disabled March 30, 2026 05:52

Head branch was pushed to by a user without write access

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review of Pull Request: Adding Function to Print Colored Terminal Output

General Feedback

The PR introduces a new feature to enhance the CLI output of the agent-governance package by adding color-coded messages using the rich library. This improves the readability and user experience of the CLI. The implementation is well-structured, and the use of helper functions for different message types ensures modularity and reusability. However, there are a few areas that require attention to ensure robustness, security, and backward compatibility.


🔴 CRITICAL

  1. Error Handling for rich Import:

    • The _import_console function catches all exceptions (except Exception) when importing rich.console.Console. This is overly broad and could mask unexpected errors unrelated to the rich library. For example, if there is a syntax error or a misconfiguration in the environment, it would silently fail and degrade to plain text output.
    • Action: Narrow the exception handling to specifically catch ModuleNotFoundError or ImportError for the rich library.
      try:
          from rich.console import Console
          return Console(stderr=use_stderr, no_color=no_color)
      except (ModuleNotFoundError, ImportError):
          return None
  2. Policy Violation Output to stderr:

    • The policy_violation() function currently outputs to stdout. However, policy violations are critical errors and should be directed to stderr to align with standard CLI practices.
    • Action: Update the policy_violation() function to use use_stderr=True when initializing the Console object.

🟡 WARNING

  1. Backward Compatibility:
    • Adding the rich library as a dependency could potentially break environments where rich is not installed or where dependency conflicts arise. While the fallback to plain text is implemented, the dependency itself may still cause issues.
    • Action: Consider marking rich as an optional dependency in pyproject.toml and provide a clear error message if it is not installed and the user explicitly requests colored output in the future (e.g., with a --color flag).

💡 SUGGESTIONS

  1. Add a --no-color Flag:

    • While the PR mentions the possibility of adding a --no-color flag in the future, it would be better to implement it now to provide users with the ability to disable colored output if needed (e.g., for logging or when piping output to a file).
    • Action: Add a --no-color flag to the CLI and pass its value to the no_color parameter in the _import_console function.
  2. Test Coverage:

    • The tests in test_cli_output.py are a good start, but they only check for the presence of specific substrings in the output. They do not verify whether the correct color codes are applied when rich is available.
    • Action: Use the rich library's Console object in the tests to capture and verify the actual styled output. For example:
      from rich.console import Console
      from io import StringIO
      
      def test_success_with_color():
          console = Console(file=StringIO(), no_color=False)
          console.print("This is a success message", style="green")
          output = console.file.getvalue()
          assert "[green]This is a success message[/green]" in output
  3. Default Behavior for no_color:

    • The no_color parameter defaults to False in the helper functions, but this is not explicitly documented in the docstrings.
    • Action: Update the docstrings for the helper functions to include the default value of no_color.
  4. Use of Unicode Characters:

    • The passed_check() function uses a Unicode checkmark (\u2714). While this enhances readability, it may not render correctly in all terminal environments.
    • Action: Provide a fallback for environments that do not support Unicode, or document this behavior in the CLI's usage notes.
  5. Test for Fallback Behavior:

    • The current tests do not verify the fallback behavior when rich is not installed.
    • Action: Add a test case that mocks the absence of the rich library (e.g., using unittest.mock) and verifies that the output falls back to plain text.
  6. Code Duplication in Helper Functions:

    • The helper functions (error, success, warn, etc.) have repetitive code for importing the console and checking for None.
    • Action: Refactor the helper functions to reduce duplication. For example:
      def _print_message(msg: str, style: str, no_color: bool, use_stderr: bool = False) -> None:
          console = _import_console(no_color, use_stderr)
          if console:
              console.print(msg, style=style)
          else:
              print(msg, file=sys.stderr if use_stderr else sys.stdout)
      
      def error(msg: str, no_color: bool = False) -> None:
          _print_message(msg, style="red", no_color=no_color, use_stderr=True)
      
      def success(msg: str, no_color: bool = False) -> None:
          _print_message(msg, style="green", no_color=no_color)
  7. Documentation Update:

    • The PR does not include updates to the documentation to reflect the new colored output feature.
    • Action: Update the CLI documentation to describe the new color-coded output and the potential addition of a --no-color flag.
  8. Logging Integration:

    • The current implementation uses print() for output. While this is fine for a CLI, integrating with Python's logging module would provide more flexibility and allow users to configure logging levels and handlers.
    • Action: Consider refactoring the CLI to use the logging module for output, with rich used for formatting the log messages.

Summary of Changes Needed

  1. 🔴 Critical: Narrow exception handling for rich import and redirect policy_violation() output to stderr.
  2. 🟡 Warning: Consider making rich an optional dependency to avoid potential backward compatibility issues.
  3. 💡 Suggestions:
    • Add a --no-color flag to the CLI.
    • Improve test coverage to verify color codes and fallback behavior.
    • Refactor helper functions to reduce code duplication.
    • Update documentation to reflect the new feature.
    • Consider integrating with the logging module for more robust output handling.

Let me know if you need further clarification or assistance!

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review of Pull Request: Adding function to print colored terminal output

General Feedback

The addition of colored terminal output using the rich library is a great enhancement for improving the user experience of the CLI. The implementation is clean, and the fallback mechanism for when rich is not installed is a thoughtful touch. Below is a detailed review of the changes, categorized by focus areas.


🔴 CRITICAL Issues

No critical security issues were identified in this pull request.


🟡 WARNING: Potential Breaking Changes

  1. Dependency Addition:

    • Adding the rich library as a dependency in pyproject.toml could potentially break environments where rich is not available or conflicts with other dependencies. While the fallback to plain text is implemented, the dependency addition should be clearly documented in the release notes, and the maintainers should ensure that this change is communicated to users.

    Action: Update the documentation and release notes to inform users about the new dependency on rich.


💡 Suggestions for Improvement

  1. Optional --no-color Flag:

    • The PR mentions the possibility of adding a --no-color flag in the future to disable colored output. This is a good idea, especially for environments where color codes may not render correctly (e.g., CI pipelines or logs). Consider implementing this feature in this PR to provide users with more control over the output format.

    Action: Add a --no-color flag to the CLI commands and pass the value to the _import_console function.

  2. Error Handling for rich Import:

    • The _import_console function currently catches all exceptions (except Exception). This is too broad and could potentially mask other issues. It would be better to catch only ImportError or ModuleNotFoundError when attempting to import rich.

    Action: Update _import_console to catch specific exceptions like ImportError or ModuleNotFoundError.

  3. Test Coverage:

    • While the new functions are tested for their output, the tests do not verify the behavior when rich is not installed. This is an important edge case to test, as the fallback to plain text is a key part of the implementation.

    Action: Add tests to simulate the absence of the rich library and verify that the fallback to plain text works as expected.

  4. Thread Safety:

    • The rich.console.Console object is instantiated multiple times in the helper functions. If these functions are called concurrently, there could be potential thread-safety issues with rich. While rich is generally thread-safe, it might be more efficient and safer to create a single Console instance and reuse it across the application.

    Action: Refactor the code to create a single Console instance (or two instances: one for stdout and one for stderr) and reuse them across the CLI functions.

  5. Default no_color Behavior:

    • The no_color parameter defaults to False in the helper functions. However, this behavior is not configurable by the user at runtime. If the --no-color flag is not implemented in this PR, consider adding an environment variable (e.g., AGENT_OS_NO_COLOR) that users can set to disable colors globally.

    Action: Add support for an environment variable to control the no_color behavior.

  6. Error Messages Consistency:

    • The error messages use the prefix ERROR: in some places and not in others. For example:
      error(f"ERROR: file not found: {path}")
      vs.
      error("ERROR: failed to load policies: {exc}")
      This inconsistency might confuse users.

    Action: Standardize error message prefixes across the CLI.

  7. Use of Unicode Characters:

    • The passed_check function uses a Unicode checkmark (\u2714). While this improves readability, it may not render correctly in all terminal environments.

    Action: Consider providing a fallback for environments that do not support Unicode characters.

  8. Documentation:

    • The PR does not include updates to the documentation. Since this change affects the CLI output, it would be helpful to update the documentation to reflect the new behavior and the potential future addition of the --no-color flag.

    Action: Update the documentation to describe the new colored output and the fallback mechanism.


Code Quality

  1. Code Duplication:

    • The helper functions (error, success, warn, etc.) have a lot of duplicated code for importing the Console and checking for its existence.

    Action: Refactor the helper functions to reduce code duplication. For example, you could create a single function that takes the message, style, and output stream as parameters.

    def print_message(msg: str, style: str, use_stderr: bool = False, no_color: bool = False) -> None:
        console = _import_console(no_color, use_stderr)
        if console:
            console.print(msg, style=style)
        else:
            print(msg, file=sys.stderr if use_stderr else sys.stdout)
    
    def error(msg: str, no_color: bool = False) -> None:
        print_message(msg, style="red", use_stderr=True, no_color=no_color)
    
    def success(msg: str, no_color: bool = False) -> None:
        print_message(msg, style="green", no_color=no_color)
  2. Function Naming:

    • The function names (error, success, etc.) are clear, but they could be more descriptive to avoid potential naming conflicts. For example, print_error instead of error.

    Action: Consider renaming the functions to more descriptive names like print_error, print_success, etc.


Backward Compatibility

The changes in this PR are non-breaking, as the CLI commands retain their existing functionality and the colored output is an enhancement. However, the addition of the rich dependency should be clearly communicated to users.


Summary of Feedback

🔴 CRITICAL

  • None identified.

🟡 WARNING

  1. Document the addition of the rich dependency to avoid potential breaking changes for users.

💡 SUGGESTIONS

  1. Implement the --no-color flag to allow users to disable colored output.
  2. Update _import_console to catch specific exceptions (ImportError or ModuleNotFoundError) instead of Exception.
  3. Add tests to verify the fallback behavior when rich is not installed.
  4. Refactor to reuse a single Console instance for thread safety and efficiency.
  5. Standardize error message prefixes for consistency.
  6. Provide a fallback for Unicode characters in passed_check.
  7. Update the documentation to reflect the new behavior and the potential addition of the --no-color flag.
  8. Refactor the helper functions to reduce code duplication.
  9. Consider more descriptive function names to avoid potential naming conflicts.

Overall, this is a well-implemented feature that enhances the usability of the CLI. Addressing the above suggestions will further improve the robustness and maintainability of the code.

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review Summary

This pull request introduces a new feature to enhance the CLI output of the agent-os package by adding colored terminal output using the rich library. The changes include helper functions for different message types, integration of these functions into existing CLI commands, and corresponding tests to ensure the functionality works as expected. While the changes improve the user experience, there are several areas that need attention to ensure security, maintainability, and backward compatibility.


🔴 CRITICAL

  1. Unvalidated Input in Output Functions:

    • The error, success, warn, policy_violation, and passed_check functions directly print user-provided strings without sanitization. This could lead to unintended consequences, such as terminal escape sequence injection.
    • Recommendation: Sanitize the input messages to ensure no malicious escape sequences can be injected. For example, use rich.text.Text.from_markup with validate=True to sanitize the input.
    from rich.text import Text
    
    def error(msg: str, no_color: bool = False) -> None:
        """Print an error message in red to stderr."""
        console = _import_console(no_color, use_stderr=True)
        if console:
            console.print(Text.from_markup(msg, validate=True), style="red")
        else:
            print(msg, file=sys.stderr)
  2. Fallback Behavior Without rich:

    • If rich is not installed, the CLI falls back to plain text output. However, this behavior is not explicitly documented or tested.
    • Recommendation: Add a clear warning message when rich is not installed, so users are aware that they are seeing plain text output. Additionally, add test cases to verify the fallback behavior.

🟡 WARNING

  1. Dependency Addition:

    • Adding rich as a dependency could potentially break environments where the library is not available or conflicts with other dependencies.
    • Recommendation: Ensure that rich is added to the requirements.txt or equivalent dependency management file. Also, consider making it an optional dependency and providing a clear error message if the library is not installed.
  2. Behavior Change in CLI Output:

    • The introduction of colored output changes the appearance of CLI messages, which could affect scripts or tools that parse the output.
    • Recommendation: Add a --no-color flag to disable colored output explicitly. This ensures backward compatibility for users who rely on plain text output.

💡 SUGGESTIONS

  1. Centralized Console Initialization:

    • The _import_console function is called multiple times in the helper functions. This could lead to redundant initialization of the Console object.
    • Recommendation: Initialize the Console object once (e.g., at the module level or in a singleton pattern) and reuse it across the helper functions.
    from rich.console import Console
    
    console = Console(stderr=False)
    error_console = Console(stderr=True)
    
    def error(msg: str, no_color: bool = False) -> None:
        """Print an error message in red to stderr."""
        if no_color:
            print(msg, file=sys.stderr)
        else:
            error_console.print(msg, style="red")
  2. Test Coverage:

    • The new test cases in test_cli_output.py are a good start, but they do not cover edge cases, such as:
      • Behavior when rich is not installed.
      • Behavior when no_color=True.
      • Handling of special characters or escape sequences in messages.
    • Recommendation: Add test cases for these scenarios to ensure robust behavior.
  3. Code Duplication in CLI Commands:

    • The CLI commands (cmd_validate, cmd_test, cmd_diff) have repetitive error-handling code that could be refactored into reusable utility functions.
    • Recommendation: Create a helper function for error handling and use it across the CLI commands.
    def handle_error(message: str, no_color: bool = False) -> int:
        error(message, no_color)
        return 2
  4. Documentation:

    • The PR mentions that documentation updates are pending. However, it is crucial to document the new colored output behavior, including the fallback mechanism and the potential --no-color flag.
    • Recommendation: Update the CLI documentation to reflect the changes and provide examples of the new output.
  5. Performance Considerations:

    • The repeated initialization of the Console object in _import_console could have a minor performance impact, especially in scripts that generate a lot of output.
    • Recommendation: As mentioned earlier, centralize the Console initialization to avoid this overhead.

Final Thoughts

This PR introduces a useful feature that improves the user experience of the CLI. However, there are critical security concerns related to unsanitized input and potential backward compatibility issues due to the change in output format. Addressing these issues and implementing the suggested improvements will ensure a more robust and secure implementation.

@imran-siddique imran-siddique enabled auto-merge (squash) March 30, 2026 06:07
auto-merge was automatically disabled March 30, 2026 06:19

Head branch was pushed to by a user without write access

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review Summary

This PR introduces a feature to add colored terminal output to the Agent-OS Python CLI using the rich library. It enhances the readability of CLI outputs by categorizing messages into different types (e.g., success, error, warning, policy violation) and assigning distinct colors to each. The implementation includes helper functions for printing colored messages and updates the CLI commands (validate, test, and diff) to use these helpers. Additionally, basic tests for the new functionality have been added.

While the feature is a welcome improvement for user experience, there are several areas that need attention, particularly around error handling, testing, and potential edge cases.


🔴 CRITICAL

  1. Improper Handling of Missing rich Library:

    • The _import_console and _import_rich_text functions print warnings to stderr if the rich library is not installed but do not raise an exception or provide a fallback mechanism for the Text class.
    • If rich is not installed, the Text.from_markup() calls will fail, leading to runtime errors.
    • Fix: Add a proper fallback mechanism for the Text class when rich is not available. For example:
      def _import_rich_text():
          try:
              from rich.text import Text
              return Text
          except ImportError:
              return None
  2. Potential Security Issue with Text.from_markup:

    • The Text.from_markup() method interprets the input string as markup. If the input string contains user-controlled data, it could lead to unexpected rendering or even security vulnerabilities.
    • Fix: Use Text(msg) instead of Text.from_markup(msg) to avoid interpreting user input as markup. If markup is necessary, sanitize the input to ensure it does not contain malicious content.

🟡 WARNING

  1. Potential Breaking Change:
    • The PR changes the CLI output format by adding colors and symbols (e.g., checkmarks). This could break any scripts or tools that rely on parsing the CLI output.
    • Action: Clearly document this change in the release notes and consider adding a --no-color flag to allow users to opt out of colored output for backward compatibility.

💡 SUGGESTIONS

  1. Improve Test Coverage:

    • The current tests only check for the presence of specific substrings in the output. They do not verify the presence of color codes or the behavior when rich is not installed.
    • Enhancement: Add tests to:
      • Verify that the output contains the expected ANSI color codes when rich is installed.
      • Verify that the fallback to plain text works correctly when rich is not installed.
      • Test the behavior of the --no-color flag (if implemented).
  2. Refactor _import_console and _import_rich_text:

    • The _import_console and _import_rich_text functions are called repeatedly in each helper function, leading to redundant imports and potential performance issues.
    • Enhancement: Refactor these functions to cache the imported modules or objects. For example:
      _console = None
      _text = None
      
      def _get_console(no_color: bool = False, use_stderr: bool = False):
          global _console
          if _console is None:
              try:
                  from rich.console import Console
                  _console = Console(stderr=use_stderr, no_color=no_color)
              except ImportError:
                  _console = None
          return _console
      
      def _get_text():
          global _text
          if _text is None:
              try:
                  from rich.text import Text
                  _text = Text
              except ImportError:
                  _text = None
          return _text
  3. Add Logging for Missing rich Library:

    • Instead of printing warnings to stderr when rich is not installed, consider using the logging module. This will allow better control over the verbosity of the messages.
    • Enhancement: Replace print() calls in _import_console and _import_rich_text with logging.warning().
  4. Optimize Helper Functions:

    • The helper functions (error, success, warn, etc.) repeat similar logic for importing Console and Text. This could be simplified by creating a single utility function that handles the common logic.
    • Enhancement: Refactor the helper functions to reduce code duplication. For example:
      def _print_message(msg: str, style: str, no_color: bool, use_stderr: bool):
          console = _get_console(no_color, use_stderr)
          Text = _get_text()
          if console and Text:
              console.print(Text(msg), style=style)
          else:
              print(msg, file=sys.stderr if use_stderr else sys.stdout)
      
      def error(msg: str, no_color: bool = False):
          _print_message(msg, "red", no_color, use_stderr=True)
      
      def success(msg: str, no_color: bool = False):
          _print_message(msg, "green", no_color, use_stderr=False)
  5. Add Type Hints:

    • The new functions and imports lack type hints, which is inconsistent with the rest of the codebase.
    • Enhancement: Add type hints to all new functions and variables. For example:
      from typing import Optional
      from rich.console import Console
      from rich.text import Text
      
      def _import_console(no_color: bool = False, use_stderr: bool = False) -> Optional[Console]:
          ...
  6. Consider Dependency Management:

    • Adding rich as a dependency increases the size of the project and may not be necessary for all users.
    • Enhancement: Consider making rich an optional dependency and provide a way to disable colored output (e.g., via a --no-color flag or an environment variable).
  7. Documentation:

    • The PR mentions that documentation updates are not included. However, this change affects the CLI behavior and should be documented.
    • Enhancement: Update the documentation to:
      • Explain the new colored output feature.
      • Provide usage examples for the CLI commands with colored output.
      • Mention the fallback behavior when rich is not installed.

Final Notes

  • The addition of colored output is a valuable enhancement for improving the user experience of the CLI.
  • Addressing the critical issues and implementing the suggested improvements will ensure the feature is robust, secure, and backward-compatible.
  • Once the above issues are resolved, this PR will be ready for approval.

@imran-siddique imran-siddique enabled auto-merge (squash) March 30, 2026 06:21
auto-merge was automatically disabled March 30, 2026 06:26

Head branch was pushed to by a user without write access

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review Summary

This pull request introduces a new feature to enhance the CLI output by adding colored text using the rich library. It also includes helper functions for different message types (e.g., errors, warnings, success messages) and updates the CLI commands to use these functions. Additionally, tests for the new functionality are included.

While the feature is a good addition for improving user experience, there are some areas that require attention to ensure robustness, maintainability, and security.


🔴 CRITICAL

  1. Unvalidated User Input in CLI Commands:

    • The CLI commands (cmd_validate, cmd_test, cmd_diff) directly use user-provided file paths without validating or sanitizing them. This could lead to potential security issues like path traversal attacks.
    • Action: Validate and sanitize user inputs to ensure they do not contain malicious paths or unexpected characters. Use libraries like os.path or pathlib to normalize paths and ensure they are within expected directories.
  2. Improper Error Handling:

    • The _import_console and _import_rich_text functions catch ModuleNotFoundError and ImportError but do not handle other potential exceptions (e.g., AttributeError if rich changes its API in the future).
    • Action: Be more specific about the exceptions you expect and handle them appropriately. For example:
      except ImportError as e:
          print(f"WARNING: {e}", file=sys.stderr)
  3. Potential Information Disclosure:

    • The error messages in cmd_validate, cmd_test, and cmd_diff may leak sensitive information (e.g., file paths, exception details) to the user.
    • Action: Avoid exposing internal details in error messages. Instead, log detailed errors for debugging purposes and provide user-friendly error messages.

🟡 WARNING

  1. Backward Compatibility:

    • The PR introduces new behavior in the CLI output by adding colors. While this is a non-breaking change for most users, it could potentially break scripts or tools that parse the CLI output.
    • Action: Add a --no-color flag as mentioned in the PR description to allow users to disable colored output. This ensures backward compatibility for users who rely on plain text output.
  2. Dependency Addition:

    • Adding the rich library as a dependency increases the attack surface of the application. While rich is a widely used library, it is important to ensure that it is actively maintained and does not introduce vulnerabilities.
    • Action: Regularly monitor the rich library for security vulnerabilities and ensure it is updated to the latest version.

💡 SUGGESTIONS

  1. Lazy Import Optimization:

    • The _import_console and _import_rich_text functions are called multiple times within each helper function, which is inefficient.
    • Action: Cache the imported Console and Text objects to avoid redundant imports. For example:
      _console = None
      _text = None
      
      def _get_console(no_color: bool = False, use_stderr: bool = False):
          global _console
          if _console is None:
              try:
                  from rich.console import Console
                  _console = Console(stderr=use_stderr, no_color=no_color)
              except ImportError:
                  print("WARNING: rich library not installed, using plain text output", file=sys.stderr)
                  _console = None
          return _console
      
      def _get_text():
          global _text
          if _text is None:
              try:
                  from rich.text import Text
                  _text = Text
              except ImportError:
                  print("WARNING: rich library not installed, using plain text output", file=sys.stderr)
                  _text = None
          return _text
  2. Test Coverage:

    • The tests for the new helper functions are basic and only check for the presence of specific substrings in the output. They do not verify the presence of color codes or styles.
    • Action: Use rich's Console object to capture the rendered output and verify that the correct styles (e.g., red, green, bold red) are applied. For example:
      from rich.console import Console
      from io import StringIO
      
      def test_success():
          console = Console(file=StringIO())
          success("This is a success message", console=console)
          output = console.file.getvalue()
          assert "[green]This is a success message[/green]" in output
  3. Error Message Consistency:

    • The error messages in the helper functions (e.g., error, policy_violation) include the word "ERROR" or "FAIL" in the message itself. This is redundant since the color and style already convey the severity.
    • Action: Remove redundant prefixes like "ERROR:" or "FAIL:" from the messages.
  4. Documentation:

    • The PR does not include any updates to the documentation, even though the CLI behavior has changed.
    • Action: Update the documentation to reflect the new colored output and provide examples of the new --no-color flag (if implemented).
  5. Default Behavior Without rich:

    • When rich is not installed, the CLI falls back to plain text output. However, this behavior is not explicitly tested.
    • Action: Add tests to verify the fallback behavior when rich is not installed. This can be done by temporarily mocking the rich import to raise an ImportError.
  6. Thread Safety:

    • The Console object is instantiated multiple times and is not thread-safe by default. If the CLI is extended to support concurrent execution in the future, this could lead to race conditions.
    • Action: Use a single shared Console instance across threads or ensure thread safety by using thread-local storage.
  7. Code Duplication:

    • The helper functions (error, success, warn, etc.) have repetitive code for importing Console and Text.
    • Action: Refactor the helper functions to reduce code duplication. For example:
      def print_message(msg: str, style: str, no_color: bool = False, use_stderr: bool = False):
          console = _get_console(no_color, use_stderr)
          Text = _get_text()
          if console and Text:
              console.print(Text(msg), style=style)
          else:
              print(msg, file=sys.stderr if use_stderr else sys.stdout)
      
      def error(msg: str, no_color: bool = False):
          print_message(msg, style="red", no_color=no_color, use_stderr=True)
      
      def success(msg: str, no_color: bool = False):
          print_message(msg, style="green", no_color=no_color)

Final Recommendations

  • Address the critical issues related to input validation, error handling, and information disclosure.
  • Implement the --no-color flag for backward compatibility.
  • Optimize the lazy import mechanism and reduce code duplication in the helper functions.
  • Enhance test coverage to include color/style validation and fallback behavior.
  • Update the documentation to reflect the new feature and its usage.

Once these issues are addressed, the PR will be ready for merging. Let me know if you need further clarification or assistance!

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review Summary

This pull request introduces a new feature to enhance the CLI output by adding colored messages using the rich library. It also includes helper functions for different message types (error, success, warn, policy_violation, passed_check) and updates the CLI commands (validate, test, diff) to use these functions. Additionally, it includes tests for the new functionality.

While the feature is a good addition for improving user experience, there are some areas that need attention to ensure security, maintainability, and compliance with best practices.


🔴 CRITICAL

  1. Unvalidated User Input in CLI Commands

    • The CLI commands (validate, test, diff) directly use user-provided file paths without sanitization or validation. This could lead to potential security issues such as path traversal attacks or arbitrary file access.
    • Action: Validate and sanitize user inputs for file paths to ensure they do not contain malicious patterns or access restricted directories.
  2. Improper Error Handling

    • The _import_console and _import_rich_text functions catch ImportError and ModuleNotFoundError but do not provide a robust fallback mechanism. If rich is not installed, the CLI will print a warning but continue execution, potentially leading to inconsistent behavior.
    • Action: Ensure that the CLI gracefully handles the absence of rich by either:
      • Enforcing rich as a required dependency (e.g., in pyproject.toml).
      • Providing a robust fallback mechanism for all cases where rich is unavailable.
  3. Potential Information Disclosure

    • The error messages in the CLI commands (e.g., cmd_validate, cmd_test, cmd_diff) expose raw exceptions (exc) to the user. This could reveal sensitive information about the system or application internals.
    • Action: Log detailed error messages internally (e.g., to a debug log) and display user-friendly error messages in the CLI.

🟡 WARNING

  1. Backward Compatibility

    • The addition of colored output may break existing automation or scripts that rely on parsing the CLI output. While the --no-color flag is mentioned in the PR description, it has not been implemented.
    • Action: Implement the --no-color flag to allow users to disable colored output and maintain backward compatibility.
  2. Dependency Addition

    • Adding rich as a dependency increases the attack surface and maintenance burden. While rich is a widely used library, its inclusion should be carefully considered.
    • Action: Evaluate whether the benefits of using rich outweigh the risks and maintenance costs. If possible, consider making it an optional dependency.

💡 SUGGESTIONS

  1. Thread Safety

    • The _import_console and _import_rich_text functions are not thread-safe. If multiple threads invoke these functions simultaneously, it could lead to race conditions.
    • Action: Use a thread-safe mechanism (e.g., threading.Lock) to ensure that the imports are performed safely.
  2. Test Coverage

    • While the new helper functions are tested, the tests only verify the presence of specific substrings in the output. They do not verify the actual color codes or styles.
    • Action: Enhance the tests to verify the presence of expected ANSI color codes in the output when rich is installed.
  3. Code Duplication

    • The helper functions (error, success, warn, policy_violation, passed_check) contain duplicated logic for importing rich components and handling fallbacks.
    • Action: Refactor the helper functions to reduce duplication. For example, create a single function that handles the common logic and accepts parameters for the message type and style.
  4. Documentation

    • The PR does not include updates to the documentation to reflect the new feature.
    • Action: Update the CLI documentation to include information about the new colored output and the planned --no-color flag.
  5. Code Style

    • The _import_console and _import_rich_text functions use inconsistent formatting (e.g., unnecessary blank lines, inconsistent use of comments).
    • Action: Clean up the formatting to improve readability and maintain consistency with the project's style guidelines.
  6. Error Message Consistency

    • The error messages in the CLI commands use different formats (e.g., some include "ERROR:" while others do not).
    • Action: Standardize the format of error messages across all commands for consistency.
  7. Performance

    • The _import_console and _import_rich_text functions are called repeatedly in the helper functions, which could lead to unnecessary overhead.
    • Action: Cache the imported rich components to avoid redundant imports.

Suggested Changes to the Code

  1. Sanitize User Input

    from pathlib import Path
    
    def sanitize_path(path: str) -> Path:
        """Sanitize and validate a file path."""
        resolved_path = Path(path).resolve()
        if not resolved_path.is_file():
            raise ValueError(f"Invalid file path: {path}")
        return resolved_path

    Use this function in CLI commands to validate file paths.

  2. Refactor Helper Functions

    from rich.console import Console
    from rich.text import Text
    
    _console = Console()
    def print_message(msg: str, style: str, use_stderr: bool = False, no_color: bool = False) -> None:
        """Print a styled message using rich, with a plain text fallback."""
        console = Console(stderr=use_stderr, no_color=no_color)
        if console:
            console.print(Text(msg), style=style)
        else:
            output = sys.stderr if use_stderr else sys.stdout
            print(msg, file=output)
    
    def error(msg: str, no_color: bool = False) -> None:
        print_message(msg, "red", use_stderr=True, no_color=no_color)
    
    def success(msg: str, no_color: bool = False) -> None:
        print_message(msg, "green", no_color=no_color)
    
    def warn(msg: str, no_color: bool = False) -> None:
        print_message(msg, "yellow", no_color=no_color)
    
    def policy_violation(msg: str, no_color: bool = False) -> None:
        print_message(msg, "bold red", use_stderr=True, no_color=no_color)
    
    def passed_check(msg: str, no_color: bool = False) -> None:
        print_message(f"\u2714 {msg}", "green", no_color=no_color)
  3. Improve Tests

    def test_success_with_color(capsys):
        success("This is a success message", no_color=False)
        captured = capsys.readouterr()
        assert "\033[32m" in captured.out  # Check for green color code
        assert "success message" in captured.out.lower()

Final Assessment

  • The feature is a good addition to improve the user experience of the CLI.
  • Address the critical security issues and backward compatibility concerns before merging.
  • Implement the suggested improvements to enhance code quality and maintainability.

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review Summary

This pull request introduces a new feature to enhance the CLI output of the agent-governance package by adding colored terminal output using the rich library. The changes improve the user experience by making the output more readable and visually distinct. The PR also includes tests for the new functionality.

While the changes are generally well-implemented, there are a few areas that require attention, including potential security concerns, code improvements, and suggestions for better practices.


🔴 CRITICAL

  1. Unvalidated User Input in CLI Commands:

    • The CLI commands (cmd_validate, cmd_test, cmd_diff) directly use user-provided file paths (args.path, args.policy, etc.) without validating them for potential directory traversal attacks or malicious inputs.
    • Recommendation: Use os.path.abspath() to normalize file paths and validate them against a whitelist of allowed directories or patterns. Additionally, ensure that symbolic links are resolved to prevent bypassing restrictions.
  2. Error Message Disclosure:

    • The error messages in the CLI commands (e.g., error(f"ERROR: failed to parse {path}: {exc}")) directly expose exception details to the user. This could potentially leak sensitive information about the system or application.
    • Recommendation: Log detailed error messages internally and display generic error messages to the user. For example:
      error(f"ERROR: Failed to parse the file at {path}. Please check the file format.")
      logger.exception("Failed to parse file: %s", path)

🟡 WARNING

  1. Backward Compatibility:
    • The introduction of colored output changes the format of CLI output. While this is a non-breaking change for most use cases, it could potentially break scripts or tools that rely on parsing the CLI output (e.g., CI pipelines).
    • Recommendation: Add a --no-color flag to allow users to disable colored output explicitly. This is already mentioned in the PR description but should be implemented in this PR to ensure backward compatibility.

💡 SUGGESTIONS

  1. Lazy Imports:

    • The _import_console and _import_rich_text functions introduce unnecessary complexity by performing lazy imports. This approach can lead to subtle bugs and makes the code harder to read.
    • Recommendation: Perform the imports at the top of the file and handle the ImportError exception there. This will simplify the code and make it easier to maintain.
  2. Default Behavior Without rich:

    • If the rich library is not installed, the CLI falls back to plain text output. However, the current implementation prints a warning message to stderr every time a function is called.
    • Recommendation: Check for the presence of rich once at the start of the program and set a global flag. Use this flag to determine whether to use colored output or plain text, without repeatedly printing warnings.
  3. Test Coverage:

    • While the new test file (test_cli_output.py) covers the basic functionality of the colored output functions, it does not test the fallback behavior when rich is not installed.
    • Recommendation: Add tests to verify that the CLI functions correctly fall back to plain text output when rich is unavailable.
  4. Error Handling in _import_console and _import_rich_text:

    • The _import_console and _import_rich_text functions catch ImportError but do not provide meaningful feedback or logging.
    • Recommendation: Log the error using a logger instead of printing to stderr.
  5. Use of Text in rich:

    • The Text class from rich.text is imported but not used effectively. For example, console.print(Text(msg), style="red") can be simplified to console.print(msg, style="red").
    • Recommendation: Remove the _import_rich_text function and directly use console.print with the style argument.
  6. Dependency Management:

    • The rich library is added as a dependency in pyproject.toml. While this is acceptable, it introduces a new runtime dependency.
    • Recommendation: Consider making rich an optional dependency and provide a clear error message if it is not installed.
  7. Code Duplication:

    • The colored output functions (error, success, warn, etc.) have repetitive code for importing Console and handling the fallback behavior.
    • Recommendation: Refactor these functions to reduce duplication. For example:
      def print_message(msg: str, style: str, use_stderr: bool = False, no_color: bool = False):
          console = _import_console(no_color, use_stderr)
          if console:
              console.print(msg, style=style)
          else:
              print(msg, file=sys.stderr if use_stderr else sys.stdout)

Additional Notes

  • Documentation: Update the CLI documentation to reflect the new colored output feature and the potential addition of a --no-color flag.
  • Logging: Consider integrating a logging framework (e.g., logging) for better error handling and debugging.
  • Performance: The repeated calls to _import_console and _import_rich_text may have a minor performance impact. Caching the Console instance could improve efficiency.

Suggested Actions

  1. Address the critical security issues related to unvalidated user input and error message disclosure.
  2. Implement the --no-color flag to ensure backward compatibility.
  3. Refactor the colored output functions to reduce duplication and improve maintainability.
  4. Add tests for fallback behavior when rich is not installed.
  5. Update documentation to reflect the changes.

Once these issues are addressed, the PR will be ready for approval.

@imran-siddique imran-siddique enabled auto-merge (squash) March 30, 2026 06:42
auto-merge was automatically disabled March 30, 2026 07:24

Head branch was pushed to by a user without write access

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review Summary

This PR introduces colored terminal output for the Agent-OS CLI using the rich library. It enhances user experience by providing visual cues for errors, warnings, successes, and policy violations. The implementation includes fallback mechanisms for environments where rich is unavailable and adds unit tests to ensure correctness.

While the feature is well-implemented and improves usability, there are a few areas that require attention, particularly regarding security, backward compatibility, and code quality.


🔴 CRITICAL

  1. Unvalidated User Input in CLI Messages:

    • The error, success, warn, policy_violation, and passed_check functions directly interpolate user-provided strings into the Text object without sanitization. This could lead to unintended behavior if malicious input is passed, especially when combined with rich's support for Markdown-like syntax.
    • Recommendation: Escape user-provided strings before passing them to Text. Use rich.text.Text.from_markup with escape=True to prevent unintended formatting or injection attacks.
    from rich.text import Text
    from rich.markup import escape
    
    def error(msg: str, no_color: bool = False) -> None:
        console = _import_console(no_color, use_stderr=True)
        if console:
            console.print(Text(escape(msg)), style="red")
        else:
            print(msg, file=sys.stderr)

🟡 WARNING

  1. Potential Breaking Change in CLI Output:

    • The introduction of colored output changes the format of CLI output, which might break scripts or tools that parse the CLI output. For example, the addition of color codes or the green checkmark () in passed_check could cause issues for downstream consumers.
    • Recommendation: Add a --no-color flag immediately to allow users to disable colored output. This will provide backward compatibility for users relying on plain-text output.
    parser.add_argument("--no-color", action="store_true", help="Disable colored output")
  2. Dependency Addition:

    • Adding rich as a dependency increases the attack surface of the project. While rich is a widely used library, it is still an additional dependency that could introduce vulnerabilities.
    • Recommendation: Ensure that rich is pinned to a specific version in pyproject.toml to avoid unexpected issues from future updates. For example:
      rich = ">=13.0.0,<14.0.0"

💡 SUGGESTIONS

  1. Lazy Import Optimization:

    • The _import_console and _import_rich_text functions are called multiple times in each helper function, which is inefficient. Consider caching the imported modules to avoid repeated imports.
    • Recommendation: Use a global variable or a class-based approach to store the Console and Text objects after the first import.
    from functools import lru_cache
    
    @lru_cache(maxsize=None)
    def _get_rich_console(no_color: bool = False, use_stderr: bool = False):
        try:
            from rich.console import Console
            return Console(stderr=use_stderr, no_color=no_color)
        except ImportError:
            return None
    
    @lru_cache(maxsize=None)
    def _get_rich_text():
        try:
            from rich.text import Text
            return Text
        except ImportError:
            return None
  2. Test Coverage:

    • While the new test_cli_output.py file provides good coverage for the new functions, the tests do not verify the fallback behavior when rich is unavailable.
    • Recommendation: Add tests that simulate the absence of rich (e.g., by mocking ImportError) to ensure the CLI gracefully falls back to plain text.
    def test_error_fallback(monkeypatch, capsys):
        monkeypatch.setattr("agent_os.policies.cli._import_console", lambda *args, **kwargs: None)
        error("This is a fallback error message")
        captured = capsys.readouterr()
        assert "fallback error message" in captured.err
  3. Documentation Update:

    • The PR does not include updates to the documentation to reflect the new colored output feature.
    • Recommendation: Update the CLI documentation to describe the new output format and the planned --no-color flag.
  4. Thread Safety:

    • The rich.console.Console object is instantiated multiple times in the CLI functions. While rich is generally thread-safe, creating multiple Console instances could lead to unexpected behavior in multi-threaded environments.
    • Recommendation: Use a single, shared Console instance for the entire CLI module.
    _console = None
    
    def _get_console(no_color: bool = False, use_stderr: bool = False):
        global _console
        if _console is None:
            from rich.console import Console
            _console = Console(stderr=use_stderr, no_color=no_color)
        return _console
  5. Error Message Consistency:

    • The error messages in the CLI functions sometimes include the prefix ERROR: or FAIL: while others do not. This inconsistency could confuse users.
    • Recommendation: Standardize error message prefixes across all functions.

Final Assessment

  • Security: 🔴 Address the unvalidated user input issue immediately.
  • Backward Compatibility: 🟡 Add a --no-color flag to avoid breaking downstream consumers.
  • Code Quality: 💡 Optimize imports, improve test coverage, and standardize error messages.

Once the critical and warning issues are addressed, this PR will be a valuable addition to the project.

Copy link
Copy Markdown
Contributor Author

@yacinemebarki yacinemebarki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR fixes the colored terminal output so that it works on non-color terminals.
Changes include:

  • Added --no-color flag
  • Updated output functions in cli.py
  • Updated tests in test_cli_output.py
  • adding test_cli_output to test

Tested using pytest.

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review Summary

This PR introduces colored terminal output for the Agent-OS CLI using the rich library. It provides utility functions for consistent formatting of messages (e.g., errors, warnings, success messages) and integrates them into existing CLI commands (validate, test, diff). The PR also includes tests for the new functionality and updates existing tests to accommodate the changes. While the feature improves CLI usability, there are a few areas that require attention, particularly around error handling, backward compatibility, and test coverage.


🔴 CRITICAL Issues

  1. Error Handling for Missing rich Library

    • The _import_console and _import_rich_text functions print warnings to stderr if rich is not installed but do not raise exceptions or provide a fallback mechanism for the caller.
    • Impact: If rich is unavailable, the CLI will silently degrade to plain text output, which might not be the intended behavior in all cases.
    • Recommendation: Explicitly document this behavior and consider adding a flag to enforce an error if rich is not installed (e.g., --require-color).
  2. Potential for Silent Failures in _import_console and _import_rich_text

    • The _import_console and _import_rich_text functions return None if rich is not installed, which could lead to unexpected behavior if the caller does not handle this case properly.
    • Recommendation: Raise a custom exception if rich is not installed, or ensure that all callers handle the None case explicitly.

🟡 WARNING Issues

  1. Backward Compatibility

    • The addition of color codes to the CLI output may break scripts or tools that parse the CLI output programmatically.
    • Recommendation: Add a --no-color flag immediately to allow users to disable colored output. This ensures backward compatibility for users relying on plain text output.
  2. Behavior Change in capsys Tests

    • The tests for CLI commands (test_policy_cli.py) have been modified to check for output in both stdout and stderr. This is a breaking change for any external tools or scripts that rely on the previous behavior of all output being sent to stdout.
    • Recommendation: Clearly document this change in the release notes and consider providing a migration guide for users.

💡 Suggestions

  1. Consolidate _import_console and _import_rich_text

    • The _import_console and _import_rich_text functions are very similar and could be combined into a single function that imports the required rich components.
    • Example:
      def _import_rich_component(component: str, no_color: bool = False, use_stderr: bool = False):
          try:
              if component == "console":
                  from rich.console import Console
                  return Console(stderr=use_stderr, no_color=no_color)
              elif component == "text":
                  from rich.text import Text
                  return Text
          except ImportError:
              print(f"WARNING: rich library not installed, using plain text output", file=sys.stderr)
              return None
  2. Test Coverage for --no-color Flag

    • While the --no-color flag is mentioned as a potential future feature, it is not implemented in this PR. Adding this flag now would improve usability and backward compatibility.
    • Recommendation: Implement the --no-color flag and add tests to verify its behavior.
  3. Test Coverage for Fallback Behavior

    • The tests do not verify the fallback behavior when rich is not installed.
    • Recommendation: Add tests that simulate the absence of rich (e.g., by mocking ModuleNotFoundError) and verify that the CLI falls back to plain text output.
  4. Use of Text Class

    • The Text class from rich.text is imported but not used effectively. For example, Text(msg) is passed to console.print() without any additional formatting.
    • Recommendation: Remove the Text class and directly pass strings to console.print() with the appropriate style argument.
  5. Error Message Consistency

    • Some error messages include the prefix ERROR:, while others do not (e.g., policy_violation messages).
    • Recommendation: Standardize error message prefixes for consistency.
  6. Dependency Management

    • The rich library is added as a dependency in pyproject.toml, but its version is not pinned to a specific range.
    • Recommendation: Pin the rich version to a specific range (e.g., rich>=13.0.0,<14.0.0) to avoid unexpected breaking changes in future releases.

Summary of Changes Needed

  1. Address the critical issues related to error handling and backward compatibility.
  2. Implement the --no-color flag for immediate backward compatibility.
  3. Add tests for fallback behavior when rich is not installed.
  4. Refactor redundant code and improve the use of the Text class.
  5. Standardize error message formatting.
  6. Pin the rich dependency version in pyproject.toml.

Once these changes are made, the PR will be in a much better state for merging. Let me know if you need further clarification or assistance!

@imran-siddique imran-siddique enabled auto-merge (squash) March 30, 2026 21:44
@imran-siddique imran-siddique merged commit 6dcdbd1 into microsoft:main Mar 30, 2026
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file size/L Large PR (< 500 lines) size/M Medium PR (< 200 lines) tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add colored terminal output to Python CLI

2 participants